package org.springframework.extend.persistence.repository.config;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;

public class SqlTemplateBeanDefinitionParser extends AbstractExtendBeanDefinitionParser implements BeanDefinitionParser {

	private static final String	TYPE_COMMON_TEMPLATE	= "common";
	private static final String	TYPE_SIMPLE_TEMPLATE	= "simple";
	private static final String	TYPE_NAMED_TEMPLATE		= "named";

	public BeanDefinition parse(Element element, ParserContext context) {
		Class templateClass = null;

		NamedNodeMap attrMap = element.getAttributes();

		// resolve jdbcTemplate type
		String type = attrMap.getNamedItem("type").getNodeValue();

		if (isCommonTemplate(type)) {
			templateClass = JdbcTemplate.class;
		} else if (isSimpleTemplate(type)) {
			// templateClass = ExtendRepositoriedSimpleJdbcTemplate.class;
			templateClass = SimpleJdbcTemplate.class;
		} else if (isNamedTemplate(type)) {
			templateClass = NamedParameterJdbcTemplate.class;
		} else {
			throw new IllegalArgumentException("Unpermitted argument! Your input type is [" + type
					+ "]. allow type is [common, simple, named].");
		}

		// resolve construct ref beans
		String targetDataSourceId = attrMap.getNamedItem("target").getNodeValue();
		ConstructorArgumentValues constructValues = new ConstructorArgumentValues();
		constructValues.addGenericArgumentValue(new RuntimeBeanReference(targetDataSourceId));

		// new beanDefinition
		RootBeanDefinition templateBeanDef = newRootBeanDefinition(element, context, templateClass, constructValues);
		MutablePropertyValues propertyValues = templateBeanDef.getPropertyValues();

		// set init method
		// templateBeanDef.setInitMethodName("initTemplate");

		// register bean definition
		BeanDefinitionReaderUtils.registerBeanDefinition(new BeanDefinitionHolder(templateBeanDef, attrMap
				.getNamedItem("id").getNodeValue()), context.getRegistry());
		return null;

	}

	private boolean isNamedTemplate(String type) {
		if (TYPE_NAMED_TEMPLATE.equals(type)) {
			return true;
		}
		return false;
	}

	private boolean isSimpleTemplate(String type) {
		if (TYPE_SIMPLE_TEMPLATE.equals(type)) {
			return true;
		}
		return false;
	}

	private boolean isCommonTemplate(String type) {
		if (TYPE_COMMON_TEMPLATE.equals(type)) {
			return true;
		}
		return false;
	}
}
